home *** CD-ROM | disk | FTP | other *** search
/ PLAYymate for OS/2 / Playmate for OS2.iso / p4os2035 / wndproc.c < prev   
C/C++ Source or Header  |  1989-02-07  |  18KB  |  531 lines

  1. /*  BioWndProc() - Parent WndProc message processing routine.
  2. *
  3. *   Created by Microsoft Corp., 1989
  4. *
  5. *   Purpose:
  6. *       WndProc callback function to handle all messages for parent window.
  7. *
  8. *   Arguments:
  9. *       hWnd          - Handle of Window owning message
  10. *       message       - Message itself
  11. *       mp1           - Extra message-dependent info
  12. *       mp2           - Extra message-dependent info
  13. *
  14. *   Globals (modified):
  15. *       Born          - Birthdate in julian days.  Read from WIN.INI.
  16. *       SelectDay     - Current day being tracked, day is highlighted.  Is
  17. *                       in units of days from birth date.  Date of present
  18. *                       day initially used in WM_CREATE.
  19. *       daylight      - Defined by environment string TZ.  If no such string,
  20. *       timezone        default TZ=PST8PDT used.  If daylight field is
  21. *                       used, daylight time correction will occur.  See
  22. *                       documentation of tzset() C run-time function.
  23. *       Day           - Day number from date born which is top line being
  24. *                       displayed.  Initially three days before SelectDay.
  25. *       bKid          - Boolean indicating whether legend is visible.
  26. *       bBorn         - Boolean indicating whether valid birtdate entered or
  27. *                       defined in WIN.INI.  Nothing graphed until valid.
  28. *       rclClient    - Size of client area defined by WM_SIZE message
  29. *       LinesPerPage  - Number of system font lines on client area, defined
  30. *                       by WM_SIZE message handling
  31. *       Color[]       - Set of colored pens used to identify cycles.
  32. *       tmFontInfo    - Text Metric structure defined during WM_CREATE 
  33. *
  34. *   Globals (referenced):
  35. *       hAB           - Handle to the Anchor Block
  36. *       hwndAppFrame  - Window handle of parent window's frame
  37. *       hwndKidFrame  - Handle to child window used for showing/moving legend.
  38. *    szAppName[]   - RC file program name (Biorhythm).
  39. *
  40. *   Description:
  41. *       Handle all messages for the parent window.
  42. *
  43. *   Limits:
  44. *       N/A
  45. *
  46. */
  47.  
  48. #define INCL_GPI
  49. #define INCL_WIN
  50. #include <os2.h>
  51.  
  52. #include "bio.h"
  53. #include <time.h>
  54. #include <stdio.h>
  55.  
  56. /* Read-only global variables */
  57. extern HAB      hAB;
  58. extern HWND     hwndApp;
  59. extern HWND     hwndAppFrame, hwndKidFrame;
  60. extern char     szAppName[];
  61. extern PFNWP OldFrameWndProc;
  62.  
  63. /* Write-once Global variables */
  64. LONG Color[] = {CLR_RED, CLR_GREEN, CLR_BLUE};
  65. FONTMETRICS     tmFontInfo;
  66. SHORT        cxLegendField;
  67. SHORT        cxDateField;
  68. /* parameter used when creating a device context for a memory device        */
  69. PSZ         dcdatablk[9] = {(PSZ)0
  70.                            ,(PSZ)"DISPLAY"
  71.                            ,(PSZ)0
  72.                            ,(PSZ)0
  73.                            ,(PSZ)0
  74.                            ,(PSZ)0
  75.                            ,(PSZ)0
  76.                            ,(PSZ)0
  77.                            ,(PSZ)0
  78.                };
  79.  
  80. /* Read-Write global variables */
  81. double          Born;
  82. long            Day, SelectDay;
  83. BOOL            bKid = TRUE;
  84. BOOL            bBorn = TRUE;
  85. RECTL           rclClient;
  86. int             LinesPerPage;
  87. void        BioGetDate(HWND);
  88.  
  89.  
  90. MRESULT CALLBACK BioWndProc( hWnd, message, mp1, mp2 )
  91. HWND   hWnd;
  92. USHORT message;
  93. MPARAM  mp1;
  94. MPARAM  mp2;
  95. {
  96.     /* Procedures which make up the window class. */
  97.     int         iDay, i;
  98.     HPS     hPS;
  99.     HPS     hMemPS;
  100.     RECTL       rc;
  101.     POINTL    ptlTextBox[5];
  102.     SIZEL    pgsi;
  103.     HDC        hdcMem;
  104.     HBITMAP    hbm;
  105.     BITMAPINFOHEADER bmih;
  106.     POINTL    ptlPoints[3];
  107.  
  108.     switch( message )
  109.     {
  110.  
  111.     case WM_CREATE:
  112.     BioGetDate(hWnd);
  113.  
  114.     /* Put date of the day three lines down on display */
  115.         Day = SelectDay - 3;
  116.  
  117.         /* Initially set elevator */
  118.         iDay = (int)(Day/365);
  119.     WinSendMsg( WinWindowFromID( WinQueryWindow(hWnd,QW_PARENT,FALSE),
  120.                      FID_VERTSCROLL),
  121.                     SBM_SETPOS, (MPARAM)MAKEULONG(iDay, 0), 0L );
  122.  
  123.         /* Get System font text metrics */
  124.         hPS = WinGetPS( hWnd );
  125.     GpiQueryFontMetrics( hPS, (LONG)sizeof tmFontInfo, &tmFontInfo );
  126.     /* Get sizes of long strings to be used as yard sticks for sizing
  127.        windows and objects.  This is necessary because of new system
  128.        proportional fonts. */
  129.     GpiQueryTextBox( hPS, 10L, "Emotional ", TXTBOX_COUNT, ptlTextBox );
  130.     cxLegendField = (SHORT)ptlTextBox[TXTBOX_CONCAT].x;
  131.     GpiQueryTextBox( hPS, 10L, "W 99-99-99", TXTBOX_COUNT, ptlTextBox );
  132.     cxDateField = (SHORT)ptlTextBox[TXTBOX_CONCAT].x;
  133.         WinReleasePS( hPS );
  134.         break;
  135.  
  136.     case WM_CLOSE:
  137.         WinPostMsg( hWnd, WM_QUIT, 0L, 0L );
  138.         break;
  139.  
  140.     case WM_COMMAND:
  141.         switch (LOUSHORT(mp1)) {
  142.             case IDM_DATES:
  143.                 if (WinDlgBox( HWND_DESKTOP, hWnd, (PFNWP)BioDlg, NULL, IDD_DATE, NULL )) {
  144.                    WinInvalidateRect( hWnd, NULL, FALSE );
  145.                    iDay = (int)(Day/365);
  146.                    WinSendMsg( WinWindowFromID( hwndAppFrame, FID_VERTSCROLL),
  147.                                SBM_SETPOS, (MPARAM)MAKEULONG(iDay, 0), 0L );
  148.                 }
  149.                 break;
  150.  
  151.         case IDM_LEGEND:
  152.                 if (bKid = !bKid) {
  153.                    WinSendMsg( WinWindowFromID( hwndAppFrame, FID_MENU),
  154.                                MM_SETITEMATTR,
  155.                    (MPARAM)MAKEULONG( IDM_LEGEND, TRUE ),
  156.                                (MPARAM)MAKEULONG( MIA_CHECKED, MIA_CHECKED) );
  157.                    WinShowWindow( hwndKidFrame, TRUE );
  158.                 } else {
  159.                    WinSendMsg( WinWindowFromID( hwndAppFrame, FID_MENU),
  160.                                MM_SETITEMATTR,
  161.                    (MPARAM)MAKEULONG( IDM_LEGEND, TRUE ),
  162.                                (MPARAM)MAKEULONG( MIA_CHECKED, 0) );
  163.                    WinShowWindow( hwndKidFrame, FALSE );
  164.                 }
  165.                 break;
  166.  
  167.         case IDM_COPY:
  168.         /* Get access to clipboard. */
  169.         WinOpenClipbrd( hAB );
  170.         /* Wipe the slate clean. */
  171.         WinEmptyClipbrd( hAB );
  172.  
  173.         /* Bitmap header for bitmap the size of the window. */
  174.         pgsi.cx = rclClient.xRight;
  175.         pgsi.cy = rclClient.yTop;
  176.         bmih.cbFix = 12;
  177.         bmih.cx = (USHORT)pgsi.cx;
  178.         bmih.cy = (USHORT)pgsi.cy;
  179.         bmih.cPlanes = 1;
  180.         bmih.cBitCount = 24;
  181.  
  182.         /* Get a memory dc. */
  183.         hdcMem = DevOpenDC( hAB
  184.                   , OD_MEMORY
  185.                   , (PSZ)"*"
  186.                   , 8L
  187.                   , (PDEVOPENDATA)dcdatablk
  188.                   , (HDC)NULL
  189.                   );
  190.  
  191.         /* Get a memory PS that will be used to manipulate image */
  192.         hMemPS = GpiCreatePS( hAB
  193.                 , hdcMem
  194.                 , (PSIZEL)&pgsi
  195.                 , (LONG)PU_PELS | GPIT_MICRO | GPIA_ASSOC
  196.                 );
  197.  
  198.         /* Create a bitmap to hold image */
  199.         hbm = GpiCreateBitmap(hMemPS, &bmih, 0L, (PBYTE)NULL, (PBITMAPINFO)NULL);
  200.         /* Select bitmap into PS */
  201.         GpiSetBitmap( hMemPS, hbm );
  202.         /* BitBlt window client area into memory bitmap */
  203.         ptlPoints[0].x = 0;
  204.         ptlPoints[0].y = 0;
  205.         ptlPoints[1].x = pgsi.cx;
  206.         ptlPoints[1].y = pgsi.cy;
  207.         ptlPoints[2].x = 0;
  208.         ptlPoints[2].y = 0;
  209.         hPS = WinGetPS( hWnd );
  210.         GpiBitBlt(hMemPS, hPS, 3L, ptlPoints, ROP_SRCCOPY, BBO_OR);
  211.         WinReleasePS( hPS );
  212.  
  213.         /* Put bitmap into the clipboard. */
  214.         WinSetClipbrdData( hAB, (ULONG)hbm, CF_BITMAP, CFI_HANDLE );
  215.  
  216.         /* Tidy up */
  217.         WinCloseClipbrd( hAB );
  218.         GpiSetBitmap( hMemPS, NULL );
  219.         GpiDestroyPS( hMemPS );
  220.         DevCloseDC( hdcMem );
  221.                 break;
  222.  
  223.             case IDM_ABOUT:
  224.                 WinDlgBox( HWND_DESKTOP, hWnd, (PFNWP)About, NULL,
  225.                            IDD_ABOUT, NULL );
  226.                 break;
  227.  
  228.             default:
  229.                 break;
  230.             }
  231.             break;
  232.  
  233.     case WM_SIZE:
  234.         WinQueryWindowRect( hWnd, &rclClient );
  235.         LinesPerPage = (int)(rclClient.yTop / tmFontInfo.lMaxBaselineExt);
  236.         WinSetWindowPos( hwndKidFrame, NULL, 10, 10, 0, 0, SWP_MOVE );
  237.         break;
  238.  
  239.     case WM_CHAR:
  240.     /* Convert keyboard to scroll bar messages to support scrolling,
  241.        paging, etc. with keyboard interface. */
  242.     if ( (ULONG)mp1 & KC_KEYUP )
  243.         return WinDefWindowProc( hWnd, message, mp1, mp2 );
  244.     switch (HIUSHORT( mp2 )) {
  245.         case VK_UP:
  246.         mp2 = (MPARAM)MAKEULONG( 0, SB_LINEUP );
  247.         break;
  248.         case VK_DOWN:
  249.         mp2 = (MPARAM)MAKEULONG( 0, SB_LINEDOWN );
  250.         break;
  251.         case VK_PAGEUP:
  252.         mp2 = (MPARAM)MAKEULONG( 0, SB_PAGEUP );
  253.         break;
  254.         case VK_PAGEDOWN:
  255.         mp2 = (MPARAM)MAKEULONG( 0, SB_PAGEDOWN );
  256.         break;
  257.         default:
  258.         return WinDefWindowProc( hWnd, message, mp1, mp2 );
  259.         break;
  260.     }
  261.     return WinSendMsg( hWnd, WM_VSCROLL, mp1, mp2 );
  262.         break;
  263.  
  264.     case WM_VSCROLL:
  265.         /* Don't allow any processing until valid birth date entered */
  266.         if (!bBorn) break;
  267.  
  268.         /* Setup for scroll window - full width of client area is scrolled */
  269.         WinCopyRect( hAB, &rc, &rclClient );
  270.         switch (HIUSHORT(mp2)) {
  271.           case SB_LINEUP:
  272.             /* Update top day of display */
  273.             Day--;
  274.             rc.yTop = rclClient.yTop - tmFontInfo.lMaxBaselineExt;
  275.             rc.yBottom = rclClient.yTop - (LinesPerPage-1) * tmFontInfo.lMaxBaselineExt + 1;
  276.             WinScrollWindow( hWnd, 0, (SHORT)-tmFontInfo.lMaxBaselineExt, &rc,
  277.                              NULL, NULL, NULL, SW_INVALIDATERGN );
  278.             break;
  279.           case SB_LINEDOWN:
  280.             /* Update top day of display */
  281.             Day++;
  282.             rc.yTop = rclClient.yTop - 2*tmFontInfo.lMaxBaselineExt;
  283.             rc.yBottom = rclClient.yTop - (LinesPerPage) * tmFontInfo.lMaxBaselineExt + 1;
  284.             WinScrollWindow( hWnd, 0, (SHORT)tmFontInfo.lMaxBaselineExt, &rc,
  285.                              NULL, NULL, NULL, SW_INVALIDATERGN );
  286.             break;
  287.           case SB_PAGEUP:
  288.             Day -= (LinesPerPage-1);
  289.             break;
  290.           case SB_PAGEDOWN:
  291.             Day += (LinesPerPage-1);
  292.             break;
  293.           case SB_SLIDERPOSITION:
  294.             /* Set to birthday of each year because 100 year scale maps to
  295.                default 100 position scroll bar */
  296.             Day = (long)(LOUSHORT(mp2) * 365.25);
  297.             break;
  298.         default:
  299.             return 0L;
  300.       }
  301.       /* Update scroll bar elevator */
  302.       iDay = (int)(Day/365);
  303.       WinSendMsg( WinWindowFromID( hwndAppFrame, FID_VERTSCROLL),
  304.                   SBM_SETPOS, (MPARAM)MAKEULONG(iDay, 0), 0L );
  305.       /* All but LINEUP/DOWN need full repaint of client area */
  306.       if ((HIUSHORT(mp2) != SB_LINEUP) && (HIUSHORT(mp2) != SB_LINEDOWN ))
  307.          WinInvalidateRect( hWnd, NULL, FALSE );
  308.       WinUpdateWindow( hWnd );
  309.       break;
  310.  
  311.     case WM_PAINT:
  312.     APPPaint( hWnd );
  313.     break;
  314.  
  315.     case WM_BUTTON1DOWN:
  316.         /* Don't allow any processing until valid birth date entered */
  317.         if (!bBorn) break;
  318.  
  319.         /* Unhighlight previously selected line and highlight new line */
  320.         WinCopyRect( hAB, &rc, &rclClient );
  321.         hPS = WinGetPS( hWnd );
  322.         for(i=0; i<2; i++) {
  323.           /* Make sure line is visible before (un)highlighting */
  324.           if ((SelectDay >= Day) && (SelectDay - Day < LinesPerPage-1)) {
  325.              rc.yTop = rclClient.yTop - (int)(SelectDay - Day + 1) * tmFontInfo.lMaxBaselineExt;
  326.              rc.yBottom = rc.yTop - tmFontInfo.lMaxBaselineExt + 1;
  327.              WinInvertRect( hPS, &rc );
  328.           }
  329.           /* New line to highlight */
  330.           SelectDay = Day + (rclClient.yTop - HIUSHORT(mp1)) / 
  331.                       tmFontInfo.lMaxBaselineExt - 1;
  332.         }
  333.         WinReleasePS( hPS );
  334.         break;
  335.  
  336.     /* Draw highlight on selected day */
  337.     if ((SelectDay >= Day) && (SelectDay - Day < LinesPerPage - 1)) {
  338.         rc.xRight = rclClient.xRight;
  339.         rc.xLeft = rclClient.xLeft;
  340.     }
  341.     default:
  342.         return WinDefWindowProc( hWnd, message, mp1, mp2 );
  343.         break;
  344.     }
  345.     return( 0L );
  346. }
  347.  
  348. /*  KidWndProc() - Child WndProc handling legend display.
  349. *
  350. *   Purpose:
  351. *       WndProc callback function to handle all messages for legend child.
  352. *
  353. *   Arguments:
  354. *       hWnd          - Handle of Window owning message
  355. *       message       - Message itself
  356. *       mp1           - Extra message-dependent info
  357. *       mp2           - Extra message-dependent info
  358. *
  359. *   Globals (referenced):
  360. *       hwndApp       - Window handle of parent window's client area
  361. *       tmFontInfo    - Text Metric structure defined during WM_CREATE 
  362. *       Color[]       - Set of colored pens used to identify cycles.
  363. *
  364. *   Description:
  365. *       Display legend information relating graph line styles to each
  366. *       cyle: physical, emotional and intellectual.  Notifies parent
  367. *       to hide child if child window is instructed to close by user.
  368. *
  369. *   Limits:
  370. *       N/A.
  371. *
  372. */
  373.  
  374. /* Read-only global variables */
  375. extern HWND     hwndApp;
  376.  
  377. MRESULT CALLBACK KidWndProc( hWnd, message, mp1, mp2 )
  378. HWND    hWnd;
  379. USHORT  message;
  380. MPARAM  mp1;
  381. MPARAM  mp2;
  382. {
  383.     HPS         hPS;
  384.     RECTL       rc;
  385.     POINTL      ptl;
  386.     int         i;
  387.  
  388.     switch( message )
  389.     {
  390.     case WM_CHAR:
  391.     /* Convert keyboard to scroll bar messages to support scrolling,
  392.        paging, etc. with keyboard interface. */
  393.     WinSendMsg( hwndApp, message, mp1, mp2 );
  394.         break;
  395.  
  396.         case WM_PAINT:
  397.             hPS = WinBeginPaint( hWnd, NULL, NULL );
  398.  
  399.         /* Erase client area */
  400.             WinQueryWindowRect( hWnd, &rc );
  401.         WinFillRect( hPS, &rc, CLR_PALEGRAY );
  402.  
  403.             ptl.x = 0;
  404.             ptl.y = tmFontInfo.lMaxDescender;
  405.         GpiCharStringAt( hPS, &ptl, 8L, (PCH)"Physical" );
  406.             ptl.y += tmFontInfo.lMaxBaselineExt;
  407.             GpiCharStringAt( hPS, &ptl, 9L, (PCH)"Emotional" );
  408.             ptl.y += tmFontInfo.lMaxBaselineExt;
  409.             GpiCharStringAt( hPS, &ptl, 9L, (PCH)"Intellect" );
  410.  
  411.             for (i=0; i<3; i++ ) {
  412.                 GpiSetColor( hPS, Color[i] );
  413.         ptl.x = cxLegendField;
  414.                 ptl.y = i * tmFontInfo.lMaxBaselineExt +
  415.                         tmFontInfo.lMaxBaselineExt/2;
  416.                 GpiMove( hPS, &ptl );
  417.         ptl.x = rc.xRight - tmFontInfo.lAveCharWidth;
  418.                 GpiLine( hPS, &ptl );
  419.             }
  420.  
  421.             WinEndPaint( hPS );
  422.             break;
  423.  
  424.     case WM_BUTTON1UP:
  425.         /* Quick way to make Legend window disappear using mouse. */
  426.         WinPostMsg( hwndApp, WM_COMMAND, (MPARAM)MAKEULONG(IDM_LEGEND, 0), 0L );
  427.             break;
  428.  
  429.     case WM_TRANSLATEACCEL:
  430.         /* Change window handle.  Child's window frame will block
  431.            ALT handling, so bypass frame.  Return window handle
  432.            of main window's client area.  Now the ALT key message
  433.            handling will be passed on up the chain of windows to
  434.            the main window's frame for proper ALT key message
  435.            handling.  The main window's menu bar will highlight
  436.            even if the child window has the focus. */
  437.         return WinDefWindowProc( hwndApp, message, mp1, mp2 );
  438.         break;
  439.  
  440.         default:
  441.             return WinDefWindowProc( hWnd, message, mp1, mp2 );
  442.             break;
  443.     }
  444.     return( 0L );
  445. }
  446. /*
  447. */
  448.  
  449. /*  FrameWndProc() - Subclass routine for frame.
  450. *
  451. *   Purpose:
  452. *    Handle WM_QUERYTRACKINFO message so that a minimum horizontal and
  453. *    vertical window size can be controled.    This minimum size keeps
  454. *    the tabulated data from overlapping and leaves at least 4 rows
  455. *    of data visible.
  456. *
  457. *   Arguments:
  458. *       hWnd          - Handle of Window owning message
  459. *       message       - Message itself
  460. *       mp1           - Extra message-dependent info
  461. *       mp2           - Extra message-dependent info
  462. *
  463. *   Globals (referenced):
  464. *    OldFrameWndProc - Original Frame Window procedure.
  465. *
  466. *   Limits:
  467. *       N/A
  468. *
  469. */
  470.  
  471. MRESULT CALLBACK FrameWndProc( hWnd, message, mp1, mp2 )
  472. HWND    hWnd;
  473. USHORT  message;
  474. MPARAM  mp1;
  475. MPARAM  mp2;
  476. {
  477.     switch( message )
  478.     {
  479.     case WM_QUERYTRACKINFO:
  480.         (*OldFrameWndProc)( hWnd, message, mp1, mp2 );
  481.         /* Limit vertical and horizontal minimum size.  Must take into
  482.            account menu, title, border and font widths and heights for
  483.            device independence. */
  484.         ((PTRACKINFO)mp2)->ptlMinTrackSize.x = cxDateField * 2 + cxDateField/2;
  485.         ((PTRACKINFO)mp2)->ptlMinTrackSize.y =
  486.         tmFontInfo.lMaxBaselineExt * 5 +
  487.         WinQuerySysValue( HWND_DESKTOP, SV_CYMENU ) +
  488.         WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +
  489.         WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER ) * 2 +
  490.         WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER ) * 2;
  491.         return TRUE;
  492.         break;
  493.  
  494.         default:
  495.         return (*OldFrameWndProc)( hWnd, message, mp1, mp2 );
  496.             break;
  497.     }
  498.     return( 0L );
  499. }
  500.  
  501. void BioGetDate(HWND hWnd) {
  502.     int         year, month;
  503.     double      day;
  504.  
  505.     /* Read in birth date from OS2.INI.  Error value is 12-31-1899,
  506.        which is out of range for valid entries. */
  507.     year = WinQueryProfileInt( hAB, szAppName, "Year", 1899 );
  508.     month = WinQueryProfileInt( hAB, szAppName, "Month", 12 );
  509.     day = (double)WinQueryProfileInt( hAB, szAppName, "Day", 31 );
  510.  
  511.     /* Compute date of birth in julian days */
  512.     Born = julian( year, month, day );
  513.  
  514.     /* Get time zone environment information */
  515.     tzset();
  516.     /*
  517.         System clock starts 1-1-1970.  Get julian date then and how many
  518.         days have elapsed since, so that number of days since birth date
  519.         can be determined
  520.     */
  521.     SelectDay  = (long)(julian( 1970, 1, 1.0 ) +
  522.        (double)((time(NULL) - timezone + (long)daylight*3600)/86400) -
  523.        Born );
  524.  
  525.     /* If no valid OS2.INI info then automatically bring up dialog box */
  526.     if (year < 1900) {
  527.        bBorn = FALSE;
  528.        WinPostMsg( hWnd, WM_COMMAND, (MPARAM)MAKEULONG(IDM_DATES, 0), 0L );
  529.     }
  530. }
  531.